
local assert     = assert
local require    = require    
local bit        = bit
local coroutine  = coroutine
local debug      = debug
local io         = io
local pairs      = pairs
local ipairs     = ipairs
local math       = math
local os         = os
local print      = print
local pcall      = pcall
local xpcall     = xpcall
local rawget     = rawget
local rawset     = rawset
local select     = select
local string     = string
local table      = table
local tonumber   = tonumber
local tostring	 = tostring
local error      = error
local type       = type
local unpack     = unpack
local setmetatable = setmetatable
local getmetatable = getmetatable
local ngx = ngx
local math_floor = math.floor

local string_format = string.format

local debug_getinfo = debug.getinfo
local os_date = os.date
local io_open = io.open

----数据变量----
local log     = require("modules.commhm.log");
local ns_http = require("modules.commhm.resty.http");
local uu      = require("modules.commhm.utils")

local table_insert = table.insert;
local table_concat = table.concat;


----使用 ngx.timer.every 和 ngx.timer.at 时候
----部分基础函数会报错，涉及ngx.var，ngx.ctx 等
----此文件对这种情况做了一层封装

------例子：
-----local CNgxTimerWrap   = require( "modules.commhm.ngxTimerWrap" )

---- local timer_ = CNgxTimerWrap:new()
---- timer_:ngx_timer_at   ( 2, my_func  )
---- timer_:ngx_timer_every( 3, my_func  )



-- _VERSION = '0.12.1'
local _M = {}
local mt = { __index = _M }

function _M.new(self, uin_)
	local ins_ = {
		uin = uin_ or 13011401          --代理账号(如果需要特殊账号，直接从参数uin_传入)
		--m_params = ngx.ctx.m_params   --请求上下文
	};
	return setmetatable(ins_, mt);
end



---针对 ngx.timer.at 的兼容封装
---@return boolean,string	同 ngx.timer.at 的返回值
function _M.ngx_timer_at( self, time_, func_, params_ )
	if  time_ and func_ then
		self.m_params = ngx.ctx.m_params or {}   --保存上下文
		if  not self.m_params.uin then
			self.m_params.uin = self.uin
		end

		local function tmp_wrap_(premature)
			if  not  ngx.ctx.m_params then
				ngx.ctx.timer_at = 1
				ngx.ctx.log      = 0
				ngx.ctx.m_params = self.m_params
				ngx.ctx.xff      = self.m_params.xff or "timer"
			end
			ngx.ctx.timer_start_time = ngx.now()
            ngx.ctx.premature = premature                        
			func_( params_ )
		end
		return ngx.timer.at( time_, tmp_wrap_ )
	end
end


---针对 ngx.timer.every 的兼容封装
---@return boolean,string	同 ngx.timer.every 的返回值
function _M.ngx_timer_every( self, time_, func_, params_ )
	if  time_ and func_ then
		self.m_params = ngx.ctx.m_params or {}  --保存上下文
		if  not self.m_params.uin then
			self.m_params.uin = self.uin
		end

		local function tmp_wrap_(premature)
			if  not  ngx.ctx.m_params then
				ngx.ctx.timer_at = 1
				ngx.ctx.log      = 0
				ngx.ctx.m_params = self.m_params
				ngx.ctx.xff      = self.m_params.xff or "timer"
			end
			ngx.ctx.timer_start_time = ngx.now()
            ngx.ctx.premature = premature            
			func_( params_ )
		end
		return ngx.timer.every( time_, tmp_wrap_ )
	end
end


--- ngx.timer.at 和 ngx.timer.every 的结合
---@param self		self
---@param delay_	number		首次延迟(秒)
---@param interval_	number		循环间隔(秒)
---@param func_		function	触发的函数
---@param params_	any			传入函数的参数
---@return boolean,string	同 ngx.timer.at 的返回值
function _M.ngx_timer( self, delay_, interval_, func_, params_ )
	if  delay_ and interval_ and func_ then
		self.m_params = ngx.ctx.m_params or {}  --保存上下文
		if  not self.m_params.uin then
			self.m_params.uin = self.uin
		end

		---循环运行
		local function loop_wrap_(premature)
			if  not  ngx.ctx.m_params then
				ngx.ctx.timer_at = 1
				ngx.ctx.log      = 0
				ngx.ctx.m_params = self.m_params
				ngx.ctx.xff      = self.m_params.xff or "timer"
			end
			ngx.ctx.timer_start_time = ngx.now()
            ngx.ctx.premature = premature
			func_( params_ )
		end

		---首次运行
		local function first_wrap_(premature)
			if  not  ngx.ctx.m_params then
				ngx.ctx.timer_at = 1
				ngx.ctx.log      = 0
				ngx.ctx.m_params = self.m_params
				ngx.ctx.xff      = self.m_params.xff or "timer"
			end
			ngx.timer.every( interval_, loop_wrap_ )
			ngx.ctx.timer_start_time = ngx.now()
            ngx.ctx.premature = premature            
			func_( params_ )
		end
		return ngx.timer.at( delay_, first_wrap_ )
	end
end



return _M;

